package com.algo.rpc.server;

import com.algo.rpc.common.RpcRequest;
import com.algo.rpc.common.RpcResponse;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.util.ReferenceCountUtil;
import org.apache.log4j.Logger;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 核心处理 handler，主要针对反序列化的请求体找到具体的处理类执行
 */
public class RpcNettyServerHandler extends ChannelInboundHandlerAdapter {

    private static final Logger logger = Logger.getLogger(RpcNettyServerHandler.class);

    private Map<Class, Class> serviceMapping = new HashMap<Class, Class>();

    public RpcNettyServerHandler(ServiceRegistry serviceRegistry) {
        this.serviceMapping = serviceRegistry.getServiceMapping();
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        RpcResponse response = new RpcResponse();
        try {
            RpcRequest request = (RpcRequest) msg;
            Class serviceImplClass = serviceMapping.get(request.getServiceInterfaceClass());
            Object serviceImpl = serviceImplClass.newInstance();
            Method method = serviceImplClass.getMethod(request.getMethodName(), request.getParameterTypes());

            logger.info("recevied request " + request);

            Object result = method.invoke(serviceImpl, request.getArgs());
            response.setRequestId(request.getRequestId());
            response.setSuccess(true);
            response.setResult(result);
        } catch (Exception e) {
            response.setSuccess(false);
            response.setError(e);
            logger.error("rpc invoke error: ", e);
        }
        logger.info("message invoke finish, return result " + response);
        // 将信息返回给客户端
        ctx.channel().writeAndFlush(response).sync();
//        ReferenceCountUtil.release(msg);
    }
}
